package org.objective.base;

import org.objective.base.annotations.Relation;
import org.objective.base.annotations.TableMapping;
import org.objective.service.Loader;
import org.objective.service.Saver;
import org.objective.ddl.NamigUtils;
import org.objective.ddl.RelationType;
import org.objective.ddl.type.DataType;

import static org.objective.base.ObjectStatus.*;
import static org.utils.fp.collection.CollectionFactory.*;

/**
 *
 * @author gus
 */
@TableMapping(mapper = BaseFieldInfo.class)
@Relation(propertyName = "owner", relationType = RelationType.Hard)
public abstract class BaseField extends BaseDomainObject implements Storable, Referable, ChildObject, Status
{
    protected BaseObject owner;
    private long fieldTypeID;
    private String fieldName;
    private String description;
    private boolean allowNull;
    private String defaultValue;
    private ObjectStatus objectStatus;

    protected BaseField(Storage storage, long id, BaseObject owner)
    {
        super(storage, id);
        this.owner = owner;
        fieldTypeID = DataType.String;
        objectStatus = CREATED;
    }

    @Override
    public BaseObject getOwner()
    {
        return owner;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public long getFieldType() throws Exception
    {
        return fieldTypeID;
    }

    public boolean isAllowNull()
    {
        return allowNull;
    }

    public void setAllowNull(boolean allowNull)
    {
        this.allowNull = allowNull;
    }

    public void setFieldType(long dataType)
    {
        fieldTypeID = dataType;
    }

    @Override
    public DomainObject getObjectRef()
    {
        return storage.stubComponent();
    }

    public String getDefaultValue()
    {
        return defaultValue;
    }

    public void setDefaultValue(String defaultValue)
    {
        this.defaultValue = defaultValue;
    }

    @Override
    public String getName()
    {
        return NamigUtils.getFieldName(id);
    }

    public String getFieldName()
    {
        return fieldName;
    }

    public void setFieldName(String fieldName)
    {
        this.fieldName = fieldName;
    }

    @Override
    public void loadData(Loader loader) throws Exception
    {
        BaseFieldInfo baseFieldInfo = loader.getField(id);

        if (baseFieldInfo != null)
        {
            setFieldName(baseFieldInfo.getName());
            id = baseFieldInfo.getId();
            uid = baseFieldInfo.getUid();
        }
    }

    @Override
    public Storable[] loadDepends()
    {
        return new Storable[0];
    }

    @Override
    public void saveData(Saver saver) throws Exception
    {
        ObjectStatus status = getObjectStatus();
        if (status != NO_CHANGE)
        {
            if (status == DELETED)
            {
                saver.deleteField(id);
            }
            else
            {
                BaseFieldInfo baseFieldInfo = new BaseFieldInfo();
                baseFieldInfo.setId(id);
                baseFieldInfo.setUid(uid);
                baseFieldInfo.setName(getFieldName());
                baseFieldInfo.setDataType(fieldTypeID);
                baseFieldInfo.setObjectRef(getObjectRef().getID());

                if (status == CREATED)
                {
                    saver.insertField(baseFieldInfo);
                }
                else
                {
                    saver.updateField(baseFieldInfo);
                }
            }
        }
        objectStatus = NO_CHANGE;
    }

    @Override
    public Storable[] saveDepends()
    {
        return array(getOwner());
    }

    @Override
    public ObjectStatus getObjectStatus()
    {
        return objectStatus;
    }
}
